home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- Talk Client written by Jeffrey A. Litz for Envoy Talk Service
-
- litz@cs.uwp.edu -or- Jeff_Litz@EDTNG.Kenosha.WI.US
-
- Copyright ©1994 JL Productions.
- *************************************************************************/
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/semaphores.h>
- #include <envoy/nipc.h>
- #include <envoy/services.h>
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/nipc_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/services_pragmas.h>
-
- #include <utility/tagitem.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/nipc_protos.h>
- #include <clib/services_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/alib_stdio_protos.h>
-
- #include <string.h>
-
- #define geta4 __builtin_geta4
- void geta4(void);
-
- #define TKCMD_TALK 1
- #define TKCMD_ABORT 2
- #define TKCMD_DATA 3
-
- struct Library *SysBase,*DOSBase,*NIPCBase,*ServicesBase;
-
- static UBYTE version[32] = {"$VER: Talk Client v1.2a"};
-
- void _main(void)
- {
- struct RDArgs *lpargs;
- void *entity, *dest, *a_entity;
- struct Transaction *trans,*a_trans;
- ULONG sigbit=0,sigbit2=0,waitmask,signal,howmany;
- ULONG args[1];
- BPTR input_w,output_w;
- ULONG done=0;
- UBYTE work_space[512],host_name[256],userinput[256];
- struct MsgPort *port,*replyport;
- struct StandardPacket *packet;
- struct TagItem cetags[4],cbtags[2],ttags[3];
-
- geta4();
- SysBase = *((struct Library **)4L);
-
- /* Initialize a bunch of stuff for setting up transactions */
-
- cetags[0].ti_Tag=ENT_Name;
- /* Assigned later */
- // cetags[0].ti_Data=NULL;
- cetags[1].ti_Tag=ENT_Public;
- cetags[1].ti_Data=NULL;
- cetags[2].ti_Tag=ENT_AllocSignal;
- cetags[2].ti_Data=(ULONG) &sigbit;
- cetags[3].ti_Tag=TAG_END;
- cetags[3].ti_Data=0;
-
- cbtags[0].ti_Tag=ENT_AllocSignal;
- cbtags[0].ti_Data=(ULONG) &sigbit2;
- cbtags[1].ti_Tag=TAG_END;
- cbtags[1].ti_Data=0;
-
- ttags[0].ti_Tag=TRN_AllocReqBuffer;
- ttags[0].ti_Data=516;
- ttags[1].ti_Tag=TRN_AllocRespBuffer;
- ttags[1].ti_Data=4;
- ttags[2].ti_Tag=TAG_END;
- ttags[2].ti_Data=0;
-
- /* open up dos library */
- if(DOSBase=OpenLibrary("dos.library", 37L))
- {
- /* Check to see if a machine to talk to was specified */
- args[0]=0;
- if(lpargs=ReadArgs("Server/A",args,NULL))
- {
- /* open up nipc library */
- if(NIPCBase=OpenLibrary("nipc.library", 0L))
- {
- /* open up services library */
- if(ServicesBase=OpenLibrary("services.library", 37L))
- {
- /* create a "near" side entity - to SEND data to service */
- if(entity=CreateEntityA((struct TagItem *) cbtags))
- {
- /* Find out exactly who WE are */
- GetHostName(entity,host_name,255);
-
- /* Setup our entity name */
- cetags[0].ti_Data=(ULONG) "talk_back";
-
- /* create a "far" side entity - to RECEIVE data from service */
- if(a_entity=CreateEntityA((struct TagItem *) cetags))
- {
- /* create a transaction for sending data to service */
- if(trans=AllocTransactionA((struct TagItem *) ttags))
- {
- /* Locate the service */
- if(dest=FindServiceA((UBYTE *)args[0], "Talk_Service", entity, NULL))
- {
- /*
- ** OK - found, now setup a transaction to
- ** send to the talk service to request a
- ** talk with us
- */
-
- *(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
- strcpy(((UBYTE *)trans->trans_RequestData+4),host_name);
- trans->trans_ReqDataActual=strlen(host_name)+4;
- trans->trans_Command=TKCMD_TALK;
- trans->trans_Timeout=10;
- DoTransaction(dest,entity,trans);
-
- /* Was there any type of transaction error? */
- if(trans->trans_Error==0)
- {
- /* Everything went OK, *PLUS* the person wishes to talk with us */
- /* Open up the input and output windows */
- if(output_w=(BPTR)Open("CON:0/0/640/150/Output Window",MODE_NEWFILE))
- {
- if(input_w=(BPTR)Open("CON:0/150/640/50/Input Window/CLOSE",MODE_NEWFILE))
- {
- /*
- ** Setup everything for reading
- ** from the input window using
- ** packets
- */
-
- /* Create a packet for reading the keyboard */
- if(packet=(struct StandardPacket *)AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR))
- {
- port=(struct MsgPort *) (((struct FileHandle *)((ULONG)input_w<<2))->fh_Type);
- if(replyport=(struct MsgPort *) CreatePort(NULL,0))
- {
- packet->sp_Msg.mn_Node.ln_Name=(char *)&(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link=&(packet->sp_Msg);
- packet->sp_Pkt.dp_Port=replyport;
- packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
- packet->sp_Pkt.dp_Arg1=34000;
- SendPkt(&packet->sp_Pkt,port,replyport);
-
- /*
- ** set the wait mask for a
- ** wait for character from
- ** the input window and for
- ** any incoming transactions
- */
-
- waitmask = (1<<replyport->mp_SigBit) | (1<<sigbit);
-
- while(!done)
- {
- signal = Wait(waitmask);
-
- /* Was there keyboard input? */
- if(signal & (1<<replyport->mp_SigBit))
- {
- /* check to make sure */
- if(GetMsg(replyport))
- {
- /* check again */
- if(packet->sp_Pkt.dp_Res1)
- {
- /* read the input */
- if(!(howmany=Read(input_w,userinput,255)))
- {
- /* close gadget - signal shut down */
- done=2;
- } else
- {
- /* Send input to our output window and send a transaction to the service to be displayed on the other side */
- userinput[howmany]=0;
- sprintf(work_space,"(%s) %s\n",host_name,userinput);
- Write(output_w,work_space,strlen(work_space));
- trans->trans_Command=TKCMD_DATA;
- *(ULONG *)(trans->trans_RequestData)=*(ULONG *)(trans->trans_ResponseData);
- strcpy(((UBYTE *)trans->trans_RequestData+4),work_space);
- trans->trans_ReqDataActual=strlen(work_space)+4;
- trans->trans_Timeout=10;
- DoTransaction(dest,entity,trans);
- }
- }
- /* setup another packet for wait for character */
- packet->sp_Pkt.dp_Port=replyport;
- packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
- packet->sp_Pkt.dp_Arg1=34000;
- SendPkt(&packet->sp_Pkt,port,replyport);
- }
- }
- /* was there a transaction? */
- if(signal & (1<<sigbit))
- {
- /* get the transaction */
- if(a_trans=GetTransaction(a_entity))
- {
- /* was it a data transaction or close down transaction */
- if(a_trans->trans_Command == TKCMD_DATA)
- {
- Write(output_w,(UBYTE *)((UBYTE *)a_trans->trans_RequestData+4),a_trans->trans_ReqDataActual-4);
- } else if(a_trans->trans_Command == TKCMD_ABORT)
- {
- done=1;
- }
-
- /* reply to the DoTransaction() from the other side */
- ReplyTransaction(a_trans);
- }
- }
- }
- /* Attempt to clear out any "left over" packet messages */
- while((ULONG *)GetMsg(replyport) != (ULONG *)&packet->sp_Msg);
- DeletePort(replyport);
- }
- /* Free up packet allocation */
- FreeMem(packet,(long)sizeof(struct StandardPacket));
- }
- /* close input and output windows */
- Close(input_w);
- }
- Close(output_w);
- }
- /* If we initiated the close down - attempt to signal other side to prevent a "hang" */
- if(done == 2)
- {
- /* Just trying to make sure the TKCMD_ABORT gets through */
-
- howmany=4;
- while(howmany--)
- {
- trans->trans_ReqDataActual=4;
- trans->trans_Command=TKCMD_ABORT;
- trans->trans_Timeout=10;
- DoTransaction(dest,entity,trans);
- if(trans->trans_Error == 0)
- {
- break;
- }
- }
- }
- } else if(trans->trans_Error == 1)
- {
- /* talk service already active */
- FPrintf(Output(),"Busy - talk already in process.\n");
- } else if(trans->trans_Error == 2)
- {
- /* we were either ignored or no one was available */
- FPrintf(Output(),"No response from talk request.\n");
- }
- /* lose the service */
- LoseService(dest);
- } else
- {
- /* something drastically went wrong */
- /* either machine doesn't exist or service isn't available on that machine */
- FPrintf(Output(),"Unable to connect with the machine or service on that machine.\n");
- }
- /* free up the transaction allocation */
- trans->trans_ReqDataLength = 516;
- FreeTransaction(trans);
- }
- /* clean up - delete/close everything */
- DeleteEntity(a_entity);
- }
- DeleteEntity(entity);
- }
- CloseLibrary(ServicesBase);
- }
- CloseLibrary(NIPCBase);
- }
- FreeArgs(lpargs);
- } else
- {
- /* readargs failed - no machine name provided */
- FPrintf(Output(),"Must provide a machine name to talk to.\n");
- }
- CloseLibrary(DOSBase);
- }
- }
-